package hos.thread.lifecycle

import android.util.Log
import androidx.annotation.MainThread
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import hos.thread.RunnableJob
import hos.thread.RunnableThis
import hos.thread.ThreadOption

/**
 * <p>Title: LifecycleRunJobLive </p>
 * <p>Description: 感知生命周期 </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @date : 2023/8/2 17:37
 * @version : 1.0
 */

class LifecycleRunJobLive<T> private constructor(
    private val data: MutableLiveData<LifecycleThreadResult> = MutableLiveData<LifecycleThreadResult>(),
    onBackground: RunnableJob<T>.() -> T,
) :
    LifecycleRunJob<T>(onBackground) {

    companion object {

        @JvmStatic
        @JvmOverloads
        fun <T> runLifecycleLive(
            lifecycleOwner: LifecycleOwner,
            job: ThreadOption.Job = ThreadOption.Job.ON,
            data: MutableLiveData<LifecycleThreadResult> = MutableLiveData<LifecycleThreadResult>(),
            onBackground: RunnableJob<T>.() -> T,
        ) = LifecycleRunJobLive<T>(data, onBackground).start(lifecycleOwner, job)

        @JvmStatic
        @JvmOverloads
        fun <T> getLifecycleLive(
            data: MutableLiveData<LifecycleThreadResult> = MutableLiveData<LifecycleThreadResult>(),
            onBackground: (RunnableJob<T>.() -> T),
        ) = LifecycleRunJobLive<T>(data, onBackground)
    }

    private val observer by lazy {
        Observer<LifecycleThreadResult>() {
            it.doFail { name ->
                postThrowable(this, name)
            }
            it.doCancel {
                postCancel(this)
            }
            it.doStart {
                postStart(this)
            }
            it.doRunning {
                postProgress(this)
            }
            it.doSuccess<T> {
                postResult(this!!)
            }
        }
    }

    @MainThread
    fun observe(
        owner: LifecycleOwner,
        observer: Observer<LifecycleThreadResult>? = null,
    ): LifecycleRunJobLive<T> {
        if (owner.lifecycle.currentState == Lifecycle.State.DESTROYED) {
            // 当前页面已经关闭
            return this
        }
        if (observer == null) {
            data.observe(owner, this.observer)
            return this
        }
        data.observe(owner, observer)
        return this
    }

    override fun progressUpdate(value: Double) {
        data.postValue(LifecycleThreadResult.RUNNING(value))
    }

    override fun start(
        lifecycleOwner: LifecycleOwner,
        job: ThreadOption.Job,
    ): RunnableJob<T> {
        if (lifecycleOwner.lifecycle.currentState == Lifecycle.State.DESTROYED) {
            // 当前页面已经关闭
            return this
        }
        this.lifecycleOwner = lifecycleOwner
        lifecycleOwner.runLifecycleUI {
            observe(lifecycleOwner)
            lifecycleOwner.lifecycle.addObserver(lifecycleObserver)
        }
        return super.start(job)
    }


    override fun run(run: RunnableThis) {
        val currentThread = Thread.currentThread()
        val threadName = currentThread.name
        try {
            if (lifecycleOwner == null) {
                return
            }
            currentThread.setUncaughtExceptionHandler { t, e ->
                data.postValue(LifecycleThreadResult.FAIL(e, t.name))
            }
            if (isCancel()) {
                // 取消
                data.postValue(LifecycleThreadResult.CANCEL())
                return
            }
            data.postValue(LifecycleThreadResult.START())
            // 运行
            val result = onBackground.invoke(this)
            if (isCancel() && isStatus(ThreadOption.Status.ON_DESTROY)) {
                // 已经取消，并且被销毁了，说明当前页面
                Log.d("Thread", "run: onCancel && onDestroy")
                return
            }
            Thread.sleep(100)
            Log.d("Thread", "run: onBackgroundSuccess")
            if (isCancel()) {
                // 取消
                data.postValue(LifecycleThreadResult.CANCEL())
                return
            }
            data.postValue(LifecycleThreadResult.SUCCESS(result))
        } catch (e: Throwable) {
            data.postValue(LifecycleThreadResult.FAIL(e, threadName))
        } finally {
            //移除所有消息.防止需要执行onCompleted了，onPrepare还没被执行，那就不需要执行了
//            MH.getHandler().removeCallbacksAndMessages(null);
            changedStatus(ThreadOption.Status.ON_DESTROY)
        }
    }

}